using System;
using Microsoft.SPOT;
using GHIElectronics.NETMF.Hardware;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.FEZ;
using System.Collections;
using System.Threading;

namespace FEZ.RNC.Library
{
    public class DS1820
    {
        public static ArrayList AvailableAddress;
        public static OneWire Ds1820Sensor;   
        Cpu.Pin pin;

        public DS1820(Cpu.Pin pin)
        {
            this.pin = pin;  
            Ds1820Sensor = new OneWire(pin);
            AvailableAddress = GetAllSensorsConnected(pin);
        }
        
        public static ArrayList GetAllSensorsConnected(Cpu.Pin pin)
        {
            ArrayList addressList = new ArrayList();
            byte[] address = new byte[8];

            if (Ds1820Sensor.Reset())
            {
                while (Ds1820Sensor.Search_GetNextDevice(address))
                {
                    //check for device signature
                    if (address[0] == 0x10) 
                    { 
                        Debug.Print("Device is a DS18S20 family device.\n");
                        addressList.Add(address);
                    }
                    else if (address[0] == 0x28) 
                    { 
                        Debug.Print("Device is a DS18B20 family device.\n");
                        addressList.Add(address);
                    }

                    //need to re initialize otherwise data will remain the same
                    address = new byte[8];
                }
            }

            return addressList;
        }
        
        public ArrayList GetAllSensorData(int timeInterval)
        {
            if (timeInterval == 0)
                timeInterval = 500; //set a default of 500 milliseconds

            ArrayList data = new ArrayList();

            foreach (byte[] address in AvailableAddress)
            {
                DS1820Data ds = new DS1820Data();
                ds.Address = address;

                if (Ds1820Sensor.Reset())
                {
                    Ds1820Sensor.WriteByte(0x55); //Match ROM
                    Ds1820Sensor.Write(address, 0, address.Length);
                    Ds1820Sensor.WriteByte(0x44); //Start conversion

                    if (Ds1820Sensor.ReadByte() == 0)
                    {
                        Ds1820Sensor.Reset();
                        Ds1820Sensor.WriteByte(0x55); // Match ROM
                        Ds1820Sensor.Write(address, 0, 8);
                        Ds1820Sensor.WriteByte(0xBE); // Read Scratchpad

                        Thread.Sleep(timeInterval); //need to wait for device

                        ushort temp = Ds1820Sensor.ReadByte(); //LSB
                        temp |= (ushort)(Ds1820Sensor.ReadByte() << 8);   // MSB

                        ds.Celcius = ((float)(temp / 16));
                        ds.Fahrenheit = (float)((1.80 * ds.Celcius) + 32.00);
                    }
                    else
                    {
                        Debug.Print("Device is not detected.");
                    }                                        
                }

                data.Add(ds);
            }

            return data;
        }

        public struct DS1820Data
        {
            public byte[] Address { get; set; }
            public float Celcius { get; set; }
            public float Fahrenheit { get; set; }
        }
    }
}
